﻿using MailKit.Net.Smtp;
using MailKit.Security;
using PMS.Core.Configuration.CommonEnumConfigs;
using PMS.Core.Utils;
using PMS.Data.Entities.Messages;
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace PMS.Services.Utils.Messages
{
    /// <summary>
    /// SMTP Builder
    /// </summary>
    public class SmtpBuilder : ISmtpBuilder
    {
        #region Ctor

        public SmtpBuilder()
        {
        }

        #endregion

        #region Methods

        /// <summary>
        /// Create a new SMTP client for a specific email account
        /// </summary>
        /// <param name="emailAccount">Email account to use</param>
        /// <returns>An SMTP client that can be used to send email messages</returns>
        public virtual SmtpClient Build(EmailAccount emailAccount)
        {
            var client = new SmtpClient
            {
                ServerCertificateValidationCallback = ValidateServerCertificate,
            };

            try
            {
                if (emailAccount is null)
                    throw new PMSException("Email account could not be null", SystemLogLevel.Error);

                client.Connect(
                    emailAccount.Host,
                    emailAccount.Port,
                    emailAccount.EnableSsl ? SecureSocketOptions.SslOnConnect : SecureSocketOptions.StartTlsWhenAvailable);

                if (emailAccount.EmailAccountType == EmailAccountType.AliyunDirectMail)
                {//阿里云邮件推送服务：阿里云邮件推送的邮件服务器为 smtpd
                 //要求要进行用户认证（要求认证用户名和发件人必须一致），认证用户名(就是发件人)和密码可以通过控制台进行设置。
                    if (string.IsNullOrEmpty(emailAccount.Username) || string.IsNullOrEmpty(emailAccount.Password))
                        throw new PMSException("Aliyun Mail Service Requires UserName and Password For Security Authentication.", SystemLogLevel.Error);
                    client.Authenticate(new NetworkCredential(emailAccount.Username, emailAccount.Password));
                }
                else //if (!string.IsNullOrWhiteSpace(emailAccount.Username))
                {//其他邮件推送或自己实现的 后续完善
                    client.Authenticate(CredentialCache.DefaultNetworkCredentials);
                }

                return client;
            }
            catch (Exception ex)
            {
                client.Dispose();
                throw new PMSException(ex.Message, SystemLogLevel.Error);
            }
        }

        /// <summary>
        /// Validates the remote Secure Sockets Layer (SSL) certificate used for authentication.
        /// </summary>
        /// <param name="sender">An object that contains state information for this validation.</param>
        /// <param name="certificate">The certificate used to authenticate the remote party.</param>
        /// <param name="chain">The chain of certificate authorities associated with the remote certificate.</param>
        /// <param name="sslPolicyErrors">One or more errors associated with the remote certificate.</param>
        /// <returns>A System.Boolean value that determines whether the specified certificate is accepted for authentication</returns>
        public virtual bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            //By default, server certificate verification is disabled.
            return true;
        }

        #endregion
    }

}
